﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using Sinacor.Infra.Service.Common;


namespace Sinacor.Servico.Bovespa.Ordens.BusinessLogic 
{
    public class ValidarDigitacao : BaseBusinessLogic
    {

        #region Constantes de Erros
        private const int ERRO_USUARIO_INSTITUCIONAL_NULL = 10;
        private const int ERRO_USUARIO_INSTITUCIONAL = 12;
        private const int ERRO_INDICADOR_SISTEMA_EXTERNO = 20;
        private const int ERRO_INDICADOR_LIQ_EXT_CLIENTE_NULL = 30;
        private const int ERRO_INDICADOR_LIQ_EXT_CLIENTE = 32;
        #endregion

        public ValidarDigitacao(){

		}

		~ValidarDigitacao(){

		}

		public virtual void Dispose(){

		}

		/// <summary>
		/// Ver regra na View, Grid :: Distribuicao - validar_Carteira
		/// 
		/// Select:
		/// select
		///  from tbomercar
		/// where cd_carliq = &lt;Carteira informada na Grid Distribuição&gt;
		///   and cd_almerc  = &lt;Mercado da Ordem/Lote&gt;
		///   and cd_natope  = &lt;Natureza de Operação da Ordem/Lote&gt;
		///   and cd_bolsa   = &lt;Bolsa da Ordem/Lote&gt;
		/// 
		/// &lt;Mercado da Ordem/Lote&gt;
		///   Se mercado da ordem/lote FRA ( fracionário ), assumir VIS ( vista )
		///   caso contrário
		///      assumir o mercado da ordem/lote
		/// </summary>
		/// <param name="pDigitacao"></param>
		public bool ValidarCarteira(BusinessEntity.BaseDigitacao pDigitacao){

            

			return true;
		}

		/// <summary>
		/// chama os metodos:
		/// ValidarClienteUsuarioAcessorAtivoSemDigito
		/// ValidarClienteFilhote
		/// ValidarClienteOrdem
		/// ValidarClienteInstitucional
		/// ValidarClienteCustodiaMercadoDerivativo
		/// 
		/// para o caso do CVM segue a query
		/// -- Código CVM
		/// 
		/// select
		///  from tscclibol
		/// where CD_OPERAC_CVM = &lt;Código CVM digitado na Grid Distribuição&gt;
		/// 
		/// -- Tipo de liquidação = '5'
		/// 
		/// select CD_CUSADR  -- custodiante
		///       CD_CLIENTE -- Código do cliente no custodiante
		///       DV_CLIENTE -- Dígito do cliente no custodiante
		///  from tgepapadr
		/// where cd_codneg = &lt;Ativo da Ordem&gt;
		/// </summary>
		/// <param name="pDigitacao"></param>

        public bool ValidarCliente(BusinessEntity.OrdemDigitacao pOrdemDigitacao)
        {
            //verificar se o cliente pertence ao grupo de acessores do usuario logado
            ValidarClienteUsuarioAcessorAtivoSemDigito(pOrdemDigitacao.CodigoCliente);
            
            //se for discricionaria o cliente deve ser filhote
            if (pOrdemDigitacao.CodigoCliente != null)
            {
                ValidarClienteFilhote(pOrdemDigitacao.CodigoCliente);                
            }
            else
            {
                ValidarClienteOrdem(pOrdemDigitacao);
            }

            if (!ValidarClienteCustodiaMercadoDerivativo(pOrdemDigitacao) || !ValidarClienteInstitucional(pOrdemDigitacao)){
                //throw;
            }

            if (!ValidarClienteCustodiaMercadoDerivativo(pOrdemDigitacao)) {
                //throw;
            }   else if (!ValidarClienteInstitucional(pOrdemDigitacao)) {
                //throw;
            }
            return false;
        }

        public bool ValidarCliente(BusinessEntity.LoteDigitacao pLoteDigitacao)
        {

            return false;
        }

        

		/// <summary>
		/// Se o mercado não for derivativo, então verificar se o cliente é custodiante ou
		/// usuario intitucional. de acordo com regra abaixo que esta na view.
		/// <b>Regra contida na view:</b>
		/// Se o cadastro deste mesmo cliente aponta agente de custódia e seu cliente e
		/// dígito ou usuário institucional e seu cliente e dígito, o Ativo que está sendo
		/// distribuído não é Derivativo e o sistema está parametrizado para não obrigar a
		/// digitação do dígito verificador do cliente,  se o cadastro do cliente possuir
		/// Agente de Custódia com o seu Cliente e Digito ou, na inexistência deste código
		/// possuir o código do Usuário Institucional com seu Cliente e Dígito, a Grid deve
		/// ter as seguintes colunas preenchidas automaticamente: Tipo de Liquidação com
		/// domínio "C" e as colunas Agente de Custodia, Cliente e Digito do Cliente no
		/// Agente de Custodia com o Agente de Custodia, Cliente e Digito no Agente de
		/// Custodia mencionados no cadastro ou, na ausência destes códigos, com o código
		/// do Usuário Institucional, Cliente e Digito no Usuário Institucional mencionados
		/// no cadastro, respectivamente.
		/// 
		/// Selects:
		/// 
		/// Cliente com agente de Custódia:
		/// select cd_custodiante agente_custodia &lt;&gt; nulo ou zero, tem agente de
		/// custódia
		/// CD_CLIE_CUST cliente_agente_custodia
		/// DV_CLIE_CUST digito_cliente_agente_custodia
		///  from tscclibol
		/// where cd_cliente = &lt;Cliente digitado na Grid Distribuição&gt;
		/// 
		/// Cliente com usuário institucional
		/// select CD_USUA_INST usuário_institucional   &lt;&gt; nulo ou zero, tem usuário
		/// institucional
		///       CD_CLIE_INST cliente_usuário_institucional
		///       DV_CLIE_INST  digito_cliente_usuário_institucional
		///  from tscclibol
		/// where cd_cliente = &lt;Cliente digitado na Grid Distribuição&gt;
		/// 
		/// Derivativos identificados pelos seguintes mercados: OPC, OPV, TER, FUT
		/// </summary>
		/// <param name="pDigitacao"></param>
		private bool ValidarClienteCustodiaMercadoDerivativo(BusinessEntity.LoteDigitacao pLoteDigitacao){

			return true;
		}

        private bool ValidarClienteCustodiaMercadoDerivativo(BusinessEntity.OrdemDigitacao pOrdemDigitacao)
        {

            return true;
        }


		/// <summary>
		/// Verificar se o cliente digitado é um cliente Filhote e não um Broker
		/// intermediario.
		/// 
		/// Select:
		/// Cliente filhote:
		/// select
		///  from tscclibol
		/// where cd_cliente = &lt;Cliente digitado na Grid Distribuição&gt;
		///   and cd_cliente_liqfin = &lt;Cliente da Ordem/Lote&gt; -- Broker
		/// Saber se é broker intermediário:
		/// select
		///  from TBORELC_BRKR
		/// where COD_BRKR_INTM = &lt;Cliente digitado na Grid Distribuição&gt;
		///   and COD_BRKR_PRIN = &lt;Cliente da Ordem/Lote&gt; -- Broker
		/// </summary>
		/// <param name="pDigitacao"></param>
        private void ValidarClienteFilhote(int? CodigoCliente)
        {
            //verificar Broker principal ou intermediario
           // if (!Cliente.ResourceAccess.Cliente().ValidarClienteBroker(CodigoCliente, CodigoCliente))
            //{
                //intermediario
               // throw;
            //}           
        }
     

		/// <summary>
		/// <font color="#ff0000"><b>ver regra na view, Grid : Distribuicao -
		/// validar_ClienteInstitucional</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarClienteInstitucional(BusinessEntity.LoteDigitacao pLoteDigitacao)
        {

			return true;
		}

        public bool ValidarClienteInstitucional(BusinessEntity.OrdemDigitacao pOrdemDigitacao)
        {

            return true;
        }

		/// <summary>
		/// Validar se o cliente é o mesmo do Lote/Ordem, e nesse caso ele apenas podera
		/// alternar entre conta de investimento e conta de deposito.
		/// </summary>
		/// <param name="pDigitacao"></param>
        private bool ValidarClienteOrdem(BusinessEntity.LoteDigitacao pLoteDigitacao)
        {

            

			return true;
		}

        private void ValidarClienteOrdem(BusinessEntity.OrdemDigitacao pOrdemDigitacao)
        {


               
        }

		/// <summary>
		/// Verifica se o cliente esta ativo e verificando a lista de acessores referente
		/// ao usuario logado.
		/// </summary>
		/// <param name="pDigitacao"></param>
        private void ValidarClienteUsuarioAcessorAtivoSemDigito(int? CodigoCliente)
        {
            Cliente.BusinessEntity.Cliente ClienteUsuarioAcessor = new Cliente.ResourceAccess.Cliente().ConsultarPorCodigoOuApelido(CodigoCliente, null, null, true);

            if (ClienteUsuarioAcessor == null)
            {
                //throw;
            }
            else if (ClienteUsuarioAcessor.Bloqueio.isBloqueado)
            {
               // throw;
            }
		}
        
        // AGUARDANDO DEFINICAO SCATULIN ############################################
		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarDigitoVerificadorClienteIntitucional(BusinessEntity.LoteDigitacao pLoteDigitacao)
        {

			return true;
		}

        public bool ValidarDigitoVerificadorClienteIntitucional(BusinessEntity.OrdemDigitacao pOrdemDigitacao)
        {

            return true;
        }

        // AGUARDANDO DEFINICAO SCATULIN ############################################
		/// <summary>
		/// <font color="#ff0000"><b>Ver regra na view em Grid : Distribuicao -
		/// validar_DigitoVerificarCliente</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarDigitoVerificarCliente(BusinessEntity.OrdemDigitacao pOrdemDigitacao)
        {

			return true;
		}

        public bool ValidarDigitoVerificarCliente(BusinessEntity.LoteDigitacao pLoteDigitacao)
        {

            return true;
        }


		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarDolar(BusinessEntity.BaseDigitacao pDigitacao)
        {

			return true;
		}

		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public string ValidarIndicadorLiquidacaoExternaCliente(BusinessEntity.BaseDigitacao pDigitacao)
        {
            if (String.IsNullOrEmpty(pDigitacao.IndicadorNaoLiquidacao))
            {
                throw new BusinessException(ERRO_INDICADOR_LIQ_EXT_CLIENTE_NULL);
            }
            else
            {
                if (pDigitacao.IndicadorNaoLiquidacao.ToUpper() != "S" && pDigitacao.IndicadorNaoLiquidacao.ToUpper() != "N")
                {
                    throw new BusinessException(ERRO_INDICADOR_LIQ_EXT_CLIENTE);
                }
            }

			return String.Empty;
		}

		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public string ValidarIndicadorSistemaExterno(BusinessEntity.BaseDigitacao pDigitacao)
        {
            if (pDigitacao.IndicadorSistemaExterno.Length != 18)
            {
                throw new BusinessException(ERRO_INDICADOR_SISTEMA_EXTERNO);
            }

			return String.Empty;
		}

		/// <summary>
		/// Ver regra na View, Grid :: Distribuicao - validar_%Reducao/Acrescimo-Total.
		/// 
		/// Select:
		/// 
		/// select pc_total, pc_corcor_prin
		///  from tscclibol
		/// where cd_cliente = &lt;Cliente digitado na Grid Distribuição&gt;
		/// 
		/// Se pc_total = 0
		///   Cliente com cobrança por Custo Total
		/// else
		///   Demais clientes
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarPercentualReducaoAcrescimo(BusinessEntity.BaseDigitacao pDigitacao)
        {

			return true;
		}

		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarPrecoDigitado(BusinessEntity.BaseDigitacao pDigitacao)
        {

			return true;
		}

		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarQuantidadeDigitada(BusinessEntity.BaseDigitacao pDigitacao)
        {

			return true;
		}

		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public bool ValidarTipoLiquidacao(BusinessEntity.BaseDigitacao pDigitacao)
        {

			return true;
		}

		/// <summary>
		/// <font color="#ff0000"><b>Ver Regra em Grid :: Distribuição</b></font>
		/// </summary>
		/// <param name="pDigitacao"></param>
        public string ValidarUsuarioInstitucional(BusinessEntity.BaseDigitacao pDigitacao)
        {
            if (String.IsNullOrEmpty(pDigitacao.IndicadorNaoLiquidacao))
            {
                throw new BusinessException(ERRO_USUARIO_INSTITUCIONAL_NULL);
            }

            if (pDigitacao.TipoLiquidacao!= null)
            {
                if (pDigitacao.CodigoClienteCustodia == null)
                {
                    throw new BusinessException(ERRO_USUARIO_INSTITUCIONAL);
                }
            }            

			return String.Empty;
		}

	}//end ValidarDigitacao

}//end namespace BusinessLogic